const koa = require('koa')
const cluster = require('cluster')
const bodyparser = require('koa-bodyparser')
const static = require('koa-static')
const compress = require('koa-compress');
const numCpu = require('os').cpus().length
const os = require('os');
const http = require('http');
const views = require('koa-views');
const path = require('path');
const puppeteer = require('puppeteer');
const koaServerHttpProxy = require("koa-server-http-proxy");
const configInfo = require('./config')
const networkInterfaces = os.networkInterfaces();
const fs = require('fs')

// 获取主机IP
let ipAddress;
Object.keys(networkInterfaces).forEach((interfaceName) => {
    const interfaceInfo = networkInterfaces[interfaceName];
    interfaceInfo.forEach((info) => {
        if (!info.internal && info.family === 'IPv4' && !ipAddress) {
            ipAddress = info.address;
        }
    });
});
console.log(ipAddress);

if (cluster.isMaster) {
    for (let i = 0; i < Math.min(configInfo.length, numCpu); i++) {
        cluster.fork();
    }
    const serve = http.createServer()
    serve.listen(3025, () => {
        console.log(`主进程在${3025}端口`)
    })
} else {
    let app = new koa()
    // app.use((ctx,next)=>{
    //     console.log(123123);
    //     next()
    // })
    const worker = cluster.worker.id
    const PORD = 3000 + worker
    const configcur = configInfo[worker - 1]
    // 代理请求
    app.use(koaServerHttpProxy(configcur.baseUrl, {
        host: ipAddress,
        target: configcur.proxyUrl,
        pathRewrite: configcur.pathRewrite,
        changeOrigin: true,
        headers: {
            "Origin": `http://${ipAddress}:${PORD}`,
            "Referer": `http://${ipAddress}:${PORD}`,
            "host": `${ipAddress}:${PORD}`
        },
    }));
    // 响应压缩
    app.use(compress({
        threshold: 2048 // 响应体积大于 2KB 时才进行压缩
    }));

    // 使用 ejs 模板引擎
    app.use(views(path.join(__dirname, 'views'), {
        extension: 'ejs'
    }));
    // 解析请求体
    app.use(bodyparser({
        enableTypes: ['json', 'form', 'text']
    }))
    const staticPath = path.join(__dirname, `\\project\\${configcur.staticPath}`)
    // 注册静态资源文件夹
    app.use(static(__dirname + `\\project\\${configcur.staticPath}`, { index: 'index.html', gzip: true }));
    // 处理SSR
    const router = require('koa-router')()

    if (configcur.SSR.length > 0) {
        for (let i = 0; i < configcur.SSR.length; i++) {
            router.get(configcur.SSR[i], async (ctx, next) => {
                // 首先判断请求来源 本机请求：外部请求先判断是否有缓存无缓存本机请求直接返回即可
                const reqHost = ctx.request.host
                if (reqHost.includes('localhost')) {
                    // 是本机
                    ctx.type = 'text/html';
                    const filePath = path.join(staticPath, 'index.html');
                    const fileContent = await fs.promises.readFile(filePath, 'utf-8');
                    ctx.body = fileContent;
                } else
                    if (!reqHost.includes('localhost')) {
                        // 外部请求 首先判断dist有没有缓存文件，没有缓存文件使用预渲染生成并且返回，生成失败则报错或者404
                        let currentName = configcur.SSR[i].replace(/\/+/g, '-')
                        try {
                            ctx.type = 'text/html';
                            const filePath = path.join(staticPath, `${currentName}.html`);
                            const fileContent = await fs.promises.readFile(filePath, 'utf-8');
                            ctx.body = fileContent;
                        } catch (error) {
                            // 读取失败
                            if (error.code === 'MODULE_NOT_FOUND') {
                                // 没有缓存的静态资源文件，本机进行预渲染缓存
                                const browser = await puppeteer.launch({
                                    headless: false,
                                    // `headless: true` (default) enables old Headless;
                                    // `headless: 'new'` enables new Headless;
                                    // `headless: false` enables "headful" mode.
                                });
                                const page = await browser.newPage();
                                // 在页面上执行操作
                                await page.goto(`http://localhost:${PORD}${configcur.SSR[i]}`);
                                await page.setViewport({ width: 1080, height: 1024 });
                                //   const title = await page.title();
                                // 将获取的结果返回给客户端
                                ctx.type = 'text/html';

                                const content = `${await page.content()}`;
                                ctx.body = content;
                                fs.writeFile(`./project/${configcur.staticPath}/${currentName}.html`, content, (err) => {
                                    if (err) throw err;
                                    console.log('文件已保存');
                                });

                            }

                        }


                    }
                // 本机请求进行编译
            });
        }
    }
    app.use(router.routes()).use(router.allowedMethods());
    // 处理404情况，返回原页面让前端处理
    app.use(async (ctx, next) => {
        await next()
        if (ctx.status === 404) {
            const filePath = path.join(staticPath, 'index.html');
            const fileContent = await fs.promises.readFile(filePath, 'utf-8');
            ctx.body = fileContent;
        }
    })
    app.use(async (ctx, next) => {
        await next()
        console.log(ctx.response)
        // ctx.body = 'Internal Server Error'
        if (ctx.response.type === 'text/html') {
            // 在这里执行你的操作
            console.log('响应类型为 HTML');
            console.log(ctx.request.header);
            console.log(ctx.query.hash);
        }
        // console.log();
        // next()
    })
    // 开启接口监听
    const serve = http.createServer(app.callback())
    serve.listen(PORD, () => {
        console.log(`集群进程在${PORD}端口`)
    })
}
